#! /usr/bin/perl -I /etc/diagela
#
# Copyright (C) 2005 IBM Corporation
#
# Author: Michael Strosaker <strosake@us.ibm.com>
#

require "servevent_parse.pl";

# Check to make sure that devices.chrp.base.ServiceRM is installed
$check = `/bin/rpm -q devices.chrp.base.ServiceRM 2>/dev/null`;
if (index($check, "ServiceRM-") == -1) {
	print "ServiceRM is not installed.\n";
#	exit 1;
}

# Wait for rmcd to start
$running = 0;
$running = 1;
$count = 0;
do {
	$check = `ps -e | grep rmcd 2>/dev/null`;
	if (index($check, "rmcd") >= 0) {
		$running = 1;
	}
	if ($running == 0) {
		$count++;
		sleep 5;
	}
} while ($running == 0 && $count < 36);		# wait about 3 minutes

if ($running == 0) {
	print "Timed out waiting for RMC daemon to start.\n";
	exit 1;
}

# Parse the serviceable event data retrieved from stdin
($se_vars, $frus, $menutext) = parse_se();

# Set call home candidate, error code, error text, and NLS support variables
#   Call Home Candidate:
#      always no for menugoals
#      always yes for SRNs
#      otherwise, check the action flag
if (defined $se_vars->{"Menu Number"}) {
	# this is a menugoal
	$call_home_candidate = "No";
	$error_code = "#".$se_vars->{"Menu Number"};
	$error_text = join(' ', @$menutext);
	$nls_support = "{\"\",\"\",\"\",\"\"}";
}
else {
	# this is an SRC or SRN
	$error_text = $se_vars->{"Text"};
	if (defined $se_vars->{"Text(Catalog,set,message)"}) {
		($cat, $set, $message) = split(/ /,
				$se_vars->{"Text(Catalog,set,message)"});
		$nls_support = "{\\\"$cat\\\",\\\"$set\\\",\\\"$message\\\",".
				"\\\"\\\"}";
	}
	else {
		$nls_support = "{\\\"\\\",\\\"\\\",\\\"\\\",\\\"\\\"}";
	}
	if (defined $se_vars->{"SRN_SRC"}) {
		# this is an SRC
		$error_code = "";
		if (hex(lc($se_vars->{"ActionFlags"})) & 0x8000) {
			$call_home_candidate = "Yes";
		}
		else {
			$call_home_candidate = "No";
		}
	}
	else {
		# this is an SRN
		$error_code = $se_vars->{"SRN"};
		$call_home_candidate = "Yes";
	}
}

# Retrieve hostname from /etc/HOSTNAME; store both fully qualified and short
$host_name = `hostname 2>/dev/null`;
if (index($host_name, ".") == -1) {
	$host_name = `hostname -f 2>/dev/null`;
}
chomp $host_name;
$partition_name = (split(/\./, $host_name))[0];

# Retrieve partition ID from /proc/device-tree/ibm,partition-no
if (-e "/proc/device-tree/ibm,partition-no") {
	$partition_no = `od -An -td /proc/device-tree/ibm,partition-no | sed "s/\\s//g" 2>/dev/null`;
	chomp $partition_no;
	if (length($partition_no) == 0) {
		$partition_no = "000".$partition_no
	}
	elsif (length($partition_no) == 1) {
		$partition_no = "00".$partition_no
	}
	elsif (length($partition_no) == 2) {
		$partition_no = "0".$partition_no
	}
}
else {
	$partition_no = "000";
}

# Retrieve CEC MTMS from /proc/device-tree/model and /proc/device-tree/system-id
$cec_machinetype = `cat /proc/device-tree/model | cut -c5- 2>/dev/null`;
chomp $cec_machinetype;
chop $cec_machinetype;
$cec_machineserial = `cat /proc/device-tree/system-id | cut -c7- 2>/dev/null`;
chomp $cec_machineserial;
chop $cec_machineserial;

# Retrieve OS description
$os = "Linux";
if (-e "/etc/SuSE-release") {
	$os .= " (Novell/SUSE)";
}
elsif (-e "/etc/redhat-release") {
	$os .= " (RedHat)";
}
#$os = `cat /etc/SuSE-release | head -1 2>/dev/null`;
#chomp $os;
#if (length($os) == 0) {
#	$os = `cat /etc/redhat-release | head -1 2>/dev/null`;
#	chomp $os;
#	if (length($os) == 0) {
#		$os = `uname -s 2>/dev/null`;
#		chomp $os;
#		if (length($os) == 0) {
#			$os = "Linux";
#		}
#	}
#}

# Determine if ibm,converged-loc-code property applies
$level = "";
if (-e "/proc/device-tree/ibm,converged-loc-codes") {
	$level = "Level=\"ibm,converged-loc-codes\" ";
}

# Retrieve Extended Error Data (EED)
mkdir "/tmp/diagSEsnap", 0775;
$general_eed_file = "/tmp/diagSEsnap/snapH.tar.gz";
system("/usr/sbin/snap -o $general_eed_file 2>/dev/null 1>&2");
$cstop_eed_file = "";

# Retrieve cluster MTMS if on a cluster
$cluster_mt = "";
$cluster_ms = "";
if (-e "/usr/lib/lscmtms") {
	$cluster_mtms = `/usr/lib/lscmtms 2>/dev/null`;
	# output of lscmtms is in the following form: "MT:<mtm> MS:<ms>"
	# anything, including spaces, can be between < and >; a space
	# precedes the MS: tag
	$start = index($cluster_mtms, "MT:<");
	if ($start >= 0) {
		$start += 4;
		$end = index($cluster_mtms, ">", $start);
		$cluster_mt = substr($cluster_mtms, $start, $end-$start);
	}

	$start = index($cluster_mtms, "MS:<");
	if ($start >= 0) {
		$start += 4;
		$end = index($cluster_mtms, ">", $start);
		$cluster_ms = substr($cluster_mtms, $start, $end-$start);
	}
}
$cluster_buffer = "{\\\"$cluster_mt\\\",\\\"$cluster_ms\\\"}";

# Create mkrsrc command line
$nodes = "Nodes=\"{[\\\"OS\\\",{\\\"$cec_machinetype\\\"},".
	"{\\\"$cec_machineserial\\\"},".
	"\\\"".$se_vars->{"Failing Device Enclosure Type-Model"}."\\\",".
	"\\\"".$se_vars->{"Failing Device Enclosure Serial"}."\\\",".
	"\\\"$error_code\\\",\\\"".$error_text."\\\",".
	"\\\"$reporting_loc_code\\\",\\\"$partition_no\\\",".
	"\\\"$partition_name\\\",\\\"$host_name\\\",\\\"$os\\\",".
	"\\\"".$se_vars->{"Date/Time"}."\\\",\\\"$last_time\\\",".
	"\\\"$err_log_resource\\\",".
	"".$se_vars->{"Error Log Sequence Number"}.",0,".
	"\\\"$general_eed_file\\\",\\\"$cstop_eed_file\\\",0,".
	"{\\\"\\\"},{\\\"\\\"},{\\\"\\\"},{\\\"\\\"},{\\\"\\\"},".
	"{\\\"\\\"},{\\\"\\\"},{\\\"\\\"},{\\\"\\\"},{\\\"\\\"},".
	"$nls_support,$cluster_buffer]}\"";

$sysrefcode = "SystemRefCode=\"".substr($se_vars->{"SRN_SRC"}, 0, 8).
	$se_vars->{"Refc2"}.$se_vars->{"Refc3"}.$se_vars->{"Refc4"}.
	$se_vars->{"Refc5"}.$se_vars->{"Refc6"}.$se_vars->{"Refc7"}.
	$se_vars->{"Refc8"}.$se_vars->{"Refc9"}."\"";

$fru_list = "FRUList=\"{";
$first_fru = 1;
foreach $fru (@$frus) {
	if ($first_fru == 0) {
		$fru_list .= ",";
	}
	$first_fru = 0;

	# FRUList data:
	#  index  1: PartNum
	#  index  5: RefCode
	#  index 12: LocCode (array of size 1)
	#  index 13: CCIN
	#  index 14: FRUSerialNum
	#  index 15: FRUClass (integer value)
	#  index 16: ReplacementGroup (aka Priority)
	$fru_list .= "[";
	@data = split / /, $fru;
	if (scalar(@data) == 3) {	# FRU line
		# data[0]=location, data[1]=p/n, data[2]=ref-code
		$fru_list .= "\\\"\\\",\\\"".$data[1]."\\\",\\\"\\\",\\\"\\\",".
			"\\\"\\\",\\\"".$data[2]."\\\",{},{},\\\"\\\",".
			"\\\"\\\",\\\"\\\",\\\"\\\",{\\\"".$data[0]."\\\"},".
			"\\\"\\\",\\\"\\\",0,\\\"\\\"";
	}
	elsif (scalar(@data) == 7) {	# FRU_SRC line
		# data[0]=priority, data[1]=type, data[2]=procedure,
		# data[3]=location, data[4]=p/n, data[5]=s/n, data[6]=ccin
		$fru_list .= "\\\"\\\",\\\"".$data[4]."\\\",\\\"\\\",\\\"\\\",".
			"\\\"\\\",\\\"\\\",{},{},\\\"\\\",\\\"\\\",\\\"\\\",".
			"\\\"\\\",{\\\"".$data[3]."\\\"},\\\"".$data[6]."\\\",".
			"\\\"".$data[5]."\\\",".$data[1].",\\\"".$data[0].
			"\\\"";
	}

	$fru_list .= "]";
}
$fru_list .= "}\"";

$command = "/usr/bin/mkrsrc IBM.ServiceEvent $level".
	"CallHomeCandidate=\"$call_home_candidate\" $nodes $sysrefcode";

if ($first_fru == 0) {
	$command .= " $fru_list";
}
if (defined $se_vars->{"PlatformId"}) {
	$command .= " PlatformLogID=".hex(lc($se_vars->{"PlatformId"}));
}
if (defined $se_vars->{"CreatorId"}) {
	$command .= " CreatorID=\"".$se_vars->{"CreatorId"}."\"";
}
if (defined $se_vars->{"SubSystemId"}) {
	$command .= " SubsystemID=".hex(lc($se_vars->{"SubSystemId"}));
}
if (defined $se_vars->{"EventSeverity"}) {
	$command .= " EventSeverity=".hex(lc($se_vars->{"EventSeverity"}));
}

system("$command\n");

exit 0;
